package com.stable.actor.demo;

import com.stable.actor.core.ActorRef;
import com.stable.actor.core.StableActor;
import com.stable.actor.messages.MessageProtocol;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Master Actor - 管理客户端和处理请求
 */
public class MasterActor extends StableActor {
    private final Map<String, ClientInfo> clients = new ConcurrentHashMap<>();
    private final AtomicInteger totalRequests = new AtomicInteger(0);
    private final AtomicInteger clientCounter = new AtomicInteger(0);

    @Override
    protected void setupMessageHandlers() {
        receiveBuilder()
                .match(MessageProtocol.Register.class, this::handleRegister)
                .match(MessageProtocol.WorkRequest.class, this::handleWorkRequest)
                .match(MessageProtocol.Heartbeat.class, this::handleHeartbeat)
                .match(String.class, this::handleStringMessage);
    }

    private void handleRegister(MessageProtocol.Register register) {
        String clientId = register.clientId;
        clients.put(clientId, new ClientInfo(clientId, register.clientType, System.currentTimeMillis()));

        System.out.println("✅ 客户端注册: " + clientId + " (" + register.clientType + ")");
        System.out.println("📊 当前客户端数: " + clients.size());

        // 发送注册确认
        getSender().tell(new MessageProtocol.RegisterAck(clientId, "SUCCESS", "欢迎加入系统"), getSelf());
    }

    private void handleWorkRequest(MessageProtocol.WorkRequest request) {
        totalRequests.incrementAndGet();
        long startTime = System.currentTimeMillis();

        // 模拟处理工作
        try {
            Thread.sleep(50 + (long)(Math.random() * 100));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }

        long processingTime = System.currentTimeMillis() - startTime;
        String result = "处理完成: " + request.task.toUpperCase() + " [请求#" + request.requestId + "]";

        MessageProtocol.WorkResponse response = new MessageProtocol.WorkResponse(
                request.clientId, request.requestId, result, processingTime);

        getSender().tell(response, getSelf());

        System.out.println("📨 处理工作请求: " + request.clientId +
                " #" + request.requestId +
                " (总请求: " + totalRequests.get() + ")");
    }

    private void handleHeartbeat(MessageProtocol.Heartbeat heartbeat) {
        ClientInfo clientInfo = clients.get(heartbeat.from);
        if (clientInfo != null) {
            clientInfo.lastHeartbeat = System.currentTimeMillis();
            System.out.println("💓 心跳: " + heartbeat.from);

            // 回复心跳
            getSender().tell(new MessageProtocol.HeartbeatAck("master"), getSelf());
        }
    }

    private void handleStringMessage(String message) {
        ActorRef currentSender = getSender();

        // 处理没有发送者的情况
        if (currentSender == null) {
            System.out.println("📨 收到无发送者消息: " + message);
            // 可以选择记录日志或者进行其他处理，但不抛出异常
            return;
        }

        try {
            // 第75行及之后的业务逻辑
            System.out.println("📨 收到来自 " + currentSender + " 的消息: " + message);
            String result = "处理结果: " + message;

            // 回复发送者
            currentSender.tell(result, getSelf());

        } catch (Exception e) {
            System.err.println("❌ 处理消息失败: " + e.getMessage());
            if (currentSender != null) {
                currentSender.tell("处理失败: " + e.getMessage(), getSelf());
            }
        }
    }

    @Override
    protected void preStart() {
        System.out.println("🎯 Master Actor启动");
    }

    @Override
    protected void postStop() {
        System.out.println("🛑 Master Actor停止, 总处理请求: " + totalRequests.get());
    }

    // 客户端信息
    private static class ClientInfo {
        final String clientId;
        final String clientType;
        final long registerTime;
        long lastHeartbeat;

        ClientInfo(String clientId, String clientType, long registerTime) {
            this.clientId = clientId;
            this.clientType = clientType;
            this.registerTime = registerTime;
            this.lastHeartbeat = registerTime;
        }
    }
}
